<template>
  <div ref="canvas"></div>
</template>

<script lang="ts" setup>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";
import { ref, onMounted } from "vue";
import Stats from "three/examples/jsm/libs/stats.module";
import {initDefaultLighting} from "@/book/ThreeUtils";
import {Geometry} from "three/examples/jsm/deprecated/Geometry";

const canvas = ref();
// 场景
const scene = new THREE.Scene();
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000000);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// 相机
const camera = new THREE.PerspectiveCamera();
camera.position.set(0, 0, 150);
camera.lookAt(0, 0, 0);
// 相机控件
const orbitControl = new OrbitControls(camera, renderer.domElement);
// 性能统计
const stat = Stats();
// 光照
initDefaultLighting(scene, undefined);
// 创建粒子
// for (let x = -15; x < 15; x++) {
//   for (let y = -10; y < 10; y++) {
//     const material = new THREE.SpriteMaterial({
//       color: Math.random() * 0xffffff
//     });
//
//     const sprite = new THREE.Sprite(material);
//     sprite.position.set(x * 4, y * 4, 0);
//     scene.add(sprite);
//   }
// }

// 用 point 模拟 Sprite 也可以达到同样的效果
const vertices = [];
const colors = [];
// const geom = new Geometry();
const material = new THREE.PointsMaterial({
  size: 2,
  vertexColors: true,
  color: 0xffffff,
});
for (let x = -15; x < 15; x++) {
  for (let y = -10; y < 10; y++) {
    vertices.push(x * 4, y * 4, 0);

    const col = new THREE.Color(Math.random() * 0xffffff);
    colors.push(col.r, col.g, col.b);
    // let particle = new THREE.Vector3(x * 4, y * 4, 0);
    // geom.vertices.push(particle);
    // geom.colors.push(new THREE.Color(Math.random() * 0xffffff));
  }
}
const geom = new THREE.BufferGeometry();
geom.attributes.position = new THREE.BufferAttribute(new Float32Array(vertices), 3);
geom.setAttribute("color", new THREE.BufferAttribute(new Float32Array(colors), 3));

const cloud = new THREE.Points(geom, material);
scene.add(cloud);

const render = () => {
  stat.update();
  orbitControl.update();

  requestAnimationFrame(render);
  renderer.render(scene, camera);
};

onMounted(() => {
  canvas.value.appendChild(stat.domElement);
  canvas.value.appendChild(renderer.domElement);
  render();
});
</script>
